package com.ybt.router.core.receiver.processor.impl;

import java.io.IOException;
import java.util.Properties;

import org.apache.log4j.Logger;

import com.ruleengine.context.IContextProperty;
import com.ruleengine.context.IWorkflowConext;
import com.ruleengine.context.IWorkflowContextConstants;
import com.ruleengine.context.impl.ContextPropertyFactory;
import com.ruleengine.context.impl.WorkflowContextFactory;
import com.ruleengine.endpoint.data.IEndpointData;
import com.ruleengine.frame.callback.IRuleEngineCallback;
import com.ruleengine.frame.exception.RuleEngineFrameException;
import com.ruleengine.frame.impl.WorkflowExecuter;
import com.ybt.context.IYBTContextConstants;
import com.ybt.context.util.ContextUtil;
import com.ybt.pub.ObjectSerializationUtil;
import com.ybt.router.client.MessageClient;
import com.ybt.router.core.message.IMSDMessage;
import com.ybt.router.core.message.IMSDMessageConstants;
import com.ybt.router.core.receiver.exception.MessageReceiverException;
import com.ybt.router.core.receiver.processor.IMessageProcessor;
import com.ybt.ruleengine.expander.router.util.RuleEngineCallbackPool;

public class BusinessMessageProcessor implements IMessageProcessor {
    private static Logger logger = Logger
            .getLogger(BusinessMessageProcessor.class);

    public void process(final IMSDMessage<byte[]> message)
            throws MessageReceiverException {
        // TODO Auto-generated method stub
        String excuteId = message
                .getProperty(IWorkflowContextConstants.WORKFLOW_EXECUTE_ID);
        if (logger.isDebugEnabled()) {
            logger.debug("excute id is " + excuteId);
        }
        // 请求的服务
        String serviceId = message.getProperty(IMSDMessageConstants.MSD_TO);

        IWorkflowConext context = null;
        IRuleEngineCallback callback = RuleEngineCallbackPool.getInstance()
                .removeRuleEngineCallback(excuteId);
        if (callback != null) {
            // 交易响应
            context = WorkflowContextFactory.getInstance()
                    .createWorkflowContext();
        } else {
            // 新的交易请求
            context = WorkflowContextFactory.getInstance()
                    .createWorkflowContext(serviceId);
        }
        if (logger.isDebugEnabled()) {
            logger
                    .debug("this is a new request, begin to create a new context for service "
                            + serviceId);
        }
        // 将消息中的属性拷贝到context中
        ContextUtil.copyPropertys(context, message);

        // 解析报文体
        byte[] body = message.getMessageBody();
        Object content = null;
        try {
            content = ObjectSerializationUtil.toObject(body);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            logger.error("deserialize message body error", e);
        }
        // 原始数据
        IContextProperty<Object> dataPro = ContextPropertyFactory.getInstance()
                .createPublicVariable(IYBTContextConstants.ORIGINAL_DATA);
        dataPro.setValue(content);
        context.setContextProperty(dataPro);

        // 如果是响应，则执行回调即可
        if (callback != null) {
            // 交易响应
            if (content instanceof IEndpointData) {
                // 便准数据
                callback.onComplete(context, (IEndpointData) content);
            } else {
                // 非标准数据
                callback.onComplete(context, null);
            }
            return;
        }

        // 交易请求
        try {
            WorkflowExecuter.getInstance().executeNonBlocking(
                    context,
                    content instanceof IEndpointData ? (IEndpointData) content
                            : null, new IRuleEngineCallback() {

                        public void onException(IWorkflowConext context,
                                Exception e) {
                            if (logger.isDebugEnabled()) {
                                logger
                                        .debug("excute service ["
                                                + message
                                                        .getProperty(IMSDMessageConstants.MSD_TO)
                                                + "] error, response the message");
                            }

                            try {
                                // 拷贝消息头
                                Properties p = ContextUtil
                                        .getSeriPropertys(context);
                                p
                                        .setProperty(
                                                IMSDMessageConstants.MSD_TO,
                                                message
                                                        .getProperty(IMSDMessageConstants.MSD_FROM));
                                p
                                        .setProperty(
                                                IMSDMessageConstants.MSD_FROM,
                                                message
                                                        .getProperty(IMSDMessageConstants.MSD_TO));
                                p
                                        .setProperty(
                                                IMSDMessageConstants.MSD_DESTINATION,
                                                message
                                                        .getProperty(IMSDMessageConstants.MSD_TO));

                                // 将异常序列化，作为消息体
                                byte[] body = e == null ? new byte[0]
                                        : ObjectSerializationUtil.toByte(e);

                                // 发送消息
                                MessageClient.getInstance().sendOneWay(body, p);

                            } catch (Exception ex) {
                                // TODO Auto-generated catch block
                                logger
                                        .error(
                                                "send the response for service ["
                                                        + message
                                                                .getProperty(IMSDMessageConstants.MSD_TO)
                                                        + "] error", ex);
                            }
                        }

                        public void onComplete(IWorkflowConext context,
                                IEndpointData data) {
                            if (logger.isDebugEnabled()) {
                                logger
                                        .debug("excute service ["
                                                + message
                                                        .getProperty(IMSDMessageConstants.MSD_TO)
                                                + "] successfully, response the message");
                            }

                            try {
                                // 拷贝消息头
                                Properties p = ContextUtil
                                        .getSeriPropertys(context);
                                p
                                        .setProperty(
                                                IMSDMessageConstants.MSD_TO,
                                                message
                                                        .getProperty(IMSDMessageConstants.MSD_FROM));
                                p
                                        .setProperty(
                                                IMSDMessageConstants.MSD_FROM,
                                                message
                                                        .getProperty(IMSDMessageConstants.MSD_TO));
                                p
                                        .setProperty(
                                                IMSDMessageConstants.MSD_DESTINATION,
                                                message
                                                        .getProperty(IMSDMessageConstants.MSD_TO));

                                //拷贝消息体
                                IContextProperty<Object> dataPro = context
                                        .getContextProperty(IYBTContextConstants.ORIGINAL_DATA);
                                byte[] body = dataPro.getValue() == null ? new byte[0]
                                        : ObjectSerializationUtil
                                                .toByte(dataPro.getValue());

                                //发送消息
                                MessageClient.getInstance().sendOneWay(body, p);

                            } catch (Exception e) {
                                // TODO Auto-generated catch block
                                logger
                                        .error(
                                                "send the response for service ["
                                                        + message
                                                                .getProperty(IMSDMessageConstants.MSD_TO)
                                                        + "] error", e);
                            }
                        }

                    });
        } catch (RuleEngineFrameException e) {
            // TODO Auto-generated catch block
            logger.error("", e);
        }
    }

}
